package com.adjaisd.scarecrow.controller;

import com.adjaisd.scarecrow.common.result.Result;
import com.adjaisd.scarecrow.common.utils.jwt.JwtUtils;
import com.adjaisd.scarecrow.entity.Board;
import com.adjaisd.scarecrow.entity.Device;
import com.adjaisd.scarecrow.entity.Quota;
import com.adjaisd.scarecrow.service.BoardService;
import com.adjaisd.scarecrow.service.DeviceService;
import com.adjaisd.scarecrow.service.QuotaService;
import com.adjaisd.scarecrow.vo.BoardQuotaVO;
import com.adjaisd.scarecrow.vo.Pager;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author adjaisd
 * @since 2022-04-28
 */
@RestController
@RequestMapping("/board")
public class BoardController {

    @Autowired
    DeviceService deviceService;

    @Autowired
    QuotaService quotaService;

    @Autowired
    BoardService boardService;

    @ApiOperation(value = "分页查询设备指标")
    @ApiImplicitParam(name = "map", required = true, value = "分页信息表", paramType = "body", dataType = "json")
    @RequestMapping(value = "/quota", method = RequestMethod.POST)
    @ResponseBody
    public Result queryQuotaPage(HttpServletRequest request, @RequestBody Map<String, String> map) {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        long userId = Long.parseLong(claims.get("id").toString());

        long page = 1L, pageSize = 10L;
        try {
            if (map.containsKey("page")) page = Long.parseLong(map.get("page"));
            if (map.containsKey("pageSize")) pageSize = Long.parseLong(map.get("pageSize"));
            IPage<Quota> quotaPage = quotaService.queryNumberQuota(userId, page, pageSize);
            return Result.succ().code(200).data("pager", new Pager<>(quotaPage)).message("分页查询设备成功");
        } catch (Exception e) {
            System.out.println(e);
            return Result.fail().code(400).message("参数错误");
        }
    }


    @ApiOperation(value = "根据指标信息查询设备分页")
    @ApiImplicitParam(name = "map", required = true, value = "分页信息表", paramType = "body", dataType = "json")
    @RequestMapping(value = "/devices", method = RequestMethod.POST)
    @ResponseBody
    public Result getDeviceByQuota(HttpServletRequest request, @RequestBody Map<String, String> map) {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        long userId = Long.parseLong(claims.get("id").toString());

        long page = 1L, pageSize = 10L;
        try {
            String quotaName = map.get("quotaName");
            String unit = map.get("unit");
            if (map.containsKey("page")) page = Long.parseLong(map.get("page"));
            if (map.containsKey("pageSize")) pageSize = Long.parseLong(map.get("pageSize"));
            Pager<Device> devicePager = deviceService.getDeviceByQuota(userId, quotaName, unit, page, pageSize);
            return Result.succ().code(200).data("page", devicePager).message("根据指标信息查询设备分页成功");
        } catch (Exception e) {
            System.out.println(e);
            return Result.fail().code(400).message("参数错误");
        }
    }

    @ApiOperation(value = "添加面板")
    @ApiImplicitParam(name = "map", required = true, value = "面板信息表", paramType = "body", dataType = "json")
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ResponseBody
    public Result addBoard(HttpServletRequest request, @RequestBody Map<String, String> map) {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        Long userId = Long.parseLong(claims.get("id").toString());

        try {
            String name = map.get("name");
            if (Strings.isNullOrEmpty(name))
                Result.fail().code(400).message("面板名不能为空");
            String quotaName = map.get("quotaName");
            String unit = map.get("unit");
            String deviceIdList = map.get("deviceIdList");
            // 检查是否存在所有设备ID
            boolean existIdList = deviceService.existAllDeviceId(userId, deviceIdList);
            if (!existIdList) return Result.fail().code(400).message("添加失败(设备信息错误)");
            // 检查是否存在指标
            Boolean existQuota = quotaService.existQuota(userId, quotaName, unit);
            if (!existQuota) return Result.fail().code(400).message("添加失败(指标信息错误)");
            // 检查是否存在面板
            Board board = boardService.getBoard(userId, name, quotaName, unit);
            Long time = new Date().getTime();
            if (board == null) {// 不存在面板
                Board b1 = new Board(null, name, time, userId, quotaName, unit, deviceIdList);
                boardService.addBoard(b1);
                Board b2 = boardService.getBoard(userId, name, quotaName, unit);
                return Result.succ().code(200).data("board", b2).message("添加面板成功");
            } else if (board.getCreateDate() == 0L) {//被删除过
                board.setCreateDate(time);
                board.setDeviceIdList(deviceIdList);
                boardService.updateById(board);
            } else {
                board.setDeviceIdList(deviceIdList);
                boardService.updateById(board);
            }
            return Result.succ().code(200).data("board", board).message("更新面板成功");
        } catch (Exception e) {
            System.out.println(e);
            return Result.fail().code(50015).message("缺少必要参数");
        }
    }

    @ApiOperation(value = "删除面板")
    @ApiImplicitParam(name = "map", required = true, value = "面板信息表", paramType = "body", dataType = "json")
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public Result delBoard(HttpServletRequest request, @RequestBody Map<String, String> map) {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        Long userId = Long.parseLong(claims.get("id").toString());

        try {
            String name = map.get("name");
            String quotaName = map.get("quotaName");
            String unit = map.get("unit");
            // 检查是否存在面板
            Board board = boardService.getBoard(userId, name, quotaName, unit);
            if (board == null)  // 不存在面板
                return Result.fail().code(400).message("不存在面板");
            else if (board.getCreateDate() == 0L)   // 面板已被删除
                return Result.fail().code(400).message("不存在面板");
            else {
                board.setCreateDate(0L);
                boardService.updateById(board);
            }
            return Result.succ().code(200).message("删除面板成功");
        } catch (Exception e) {
            System.out.println(e);
            return Result.fail().code(50015).message("缺少必要参数");
        }
    }

    @ApiOperation(value = "面板预览")
    @ApiImplicitParam(name = "map", required = true, value = "面板信息表", paramType = "body", dataType = "json")
    @RequestMapping(value = "/preview", method = RequestMethod.POST)
    @ResponseBody
    public Result getPreviewData(HttpServletRequest request, @RequestBody Map<String, String> map) {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        Long userId = Long.parseLong(claims.get("id").toString());

        String quotaName = map.get("quotaName");
        String unit = map.get("unit");
        String deviceIdList = map.get("deviceIdList");
        String beg = map.get("beg");
        String end = map.get("end");
        int type = Integer.parseInt(map.get("type"));
        BoardQuotaVO boardData = boardService.getPreviewData(userId, quotaName, unit, deviceIdList, beg, end, type);
        //时间处理
        List<String> xData = Lists.newArrayList();
        for (String x : boardData.getXData()) xData.add(formatTime(x, type));
        boardData.setXData(xData);
        return Result.succ().code(200).data("preview", boardData).message("查询预览数据成功");
    }

    // 自定义面板展示过程
    // 进入页面 -> 请求所有面板的面板列表 -> 对每个面板请求指标数据
    @ApiOperation(value = "请求面板列表")
    @ApiImplicitParam(name = "map", required = true, value = "面板指标信息表", paramType = "body", dataType = "json")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ResponseBody
    public Result getBoardList(HttpServletRequest request) {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        Long userId = Long.parseLong(claims.get("id").toString());

        List<Board> boardList = boardService.getAllBoard(userId);
        return Result.succ().code(200).data("list", boardList).message("查询面板列表成功");
    }

    @ApiOperation(value = "查询预览多指标数据")
    @ApiImplicitParam(name = "map", required = true, value = "面板指标信息表", paramType = "body", dataType = "json")
    @RequestMapping(value = "/quota-data", method = RequestMethod.POST)
    @ResponseBody
    public Result getQuotaData(HttpServletRequest request, @RequestBody Map<String, String> map) {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        Long userId = Long.parseLong(claims.get("id").toString());

        try {
            String beg = map.get("beg");
            String end = map.get("end");
            int type = Integer.parseInt(map.get("type"));
            String boardId = map.get("boardId");
            Board board = boardService.getById(boardId);
            if (board == null || board.getCreateDate() == 0L)
                return Result.fail().code(400).message("面板不存在");
            else if (!board.getUserId().equals(userId))
                return Result.fail().code(400).message("没有该面板");
            else {
                BoardQuotaVO boardData = boardService.getBoardData(boardId, beg, end, type);
                //时间处理
                List<String> xData = Lists.newArrayList();
                for (String x : boardData.getXData()) xData.add(formatTime(x, type));
                boardData.setXData(xData);
                return Result.succ().code(200).data("boardData", boardData).message("查询多指标数据成功");
            }
        } catch (Exception e) {
            System.out.println(e);
            return Result.fail().code(50015).message("缺少必要参数");
        }
    }

    private String formatTime(String time, int type) {
        LocalDateTime localDateTime = LocalDateTime.parse(time, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
        if (type == 1) {
            return localDateTime.getMinute() + "";
        }
        if (type == 2) {
            return localDateTime.getHour() + "";
        }
        if (type == 3) {
            return localDateTime.getMonthValue() + "月" + localDateTime.getDayOfMonth() + "日";
        }
        return time;
    }

}
